package org.patterns.behavior.interpreter;

import java.util.ArrayDeque;
import java.util.Deque;

//指令处理类：工具类
public class InstructionHandler {
    private AbstractNode node;

    /**
     * 处理指令字符串，构建相应的抽象语法树
     * 该方法通过解析输入的指令字符串，将其转换为一系列嵌套的节点对象，从而形成一棵抽象语法树（AST）
     * 这棵树可以用来进一步解释或执行指令
     *
     * @param instruction 指令字符串，包含一系列由空格分隔的单词
     */
    public void handle(String instruction) {
        // 初始化节点变量，用于构建抽象语法树
        AbstractNode left = null;
        AbstractNode right = null;
        AbstractNode direction = null;
        AbstractNode action = null;
        AbstractNode distance = null;

        // 声明一个栈对象用于存储抽象语法树
        Deque<AbstractNode> stack = new ArrayDeque<AbstractNode>();

        // 以空格分隔指令字符串
        String[] words = instruction.split(" ");

        // 遍历指令字符串中的每个单词
        for (int i = 0; i < words.length; i++) {
            // 本实例采用栈的方式来处理指令，如果遇到“and”，则将其后的三个单词作为三个终结符表达式连成一个简单句子SentenceNode作为“and”的右表达式，
            // 而将从栈顶弹出的表达式作为“and”的左表达式，最后将新的“and”表达式压入栈中。
            if (words[i].equalsIgnoreCase("and")) {
                // 弹出栈顶表达式作为左表达式
                left = stack.pop();
                // 读取接下来的三个单词，分别创建方向、动作和距离节点
                String word1 = words[++i];
                direction = new DirectionNode(word1);
                String word2 = words[++i];
                action = new ActionNode(word2);
                String word3 = words[++i];
                distance = new DistanceNode(word3);
                // 将三个节点连成一个简单句子节点作为右表达式
                right = new SentenceNode(direction, action, distance);
                // 将左右表达式连成一个新的“and”节点，并压入栈中
                stack.push(new AndNode(left, right));
            }
            // 如果是从头开始进行解释，则将前三个单词组成一个简单句子SentenceNode并将该句子压入栈中
            else {
                // 读取当前及接下来的两个单词，分别创建方向、动作和距离节点
                String word1 = words[i];
                direction = new DirectionNode(word1);
                String word2 = words[++i];
                action = new ActionNode(word2);
                String word3 = words[++i];
                distance = new DistanceNode(word3);
                // 将三个节点连成一个简单句子节点
                left = new SentenceNode(direction, action, distance);
                // 将新表达式压入栈中
                stack.push(left);
            }
        }
        // 将全部表达式从栈中弹出，最终栈中剩下的应该就是整棵抽象语法树的根节点
        this.node = stack.pop();
    }

    public String output() {
        if (node == null) {
            throw new IllegalStateException("尚未处理任何指令。");
        }
        String result = node.interpret(); //解释表达式
        return result;
    }
}